/*
 * @Author: SunZhao
 * @Date: 2020-12-09 10:55:18
 * @LastEditTime: 2021-01-21 10:29:08
 * @LastEditors: SunZhao
 * @Description: 设备音频数据 web 调试工具
 * @FilePath: /bleDataTools/js/index.js
 */
const textarea = document.getElementById("textarea");
const package = document.getElementById("package");
const dataCMD = document.getElementById("dataCMD");
const dataLen = document.getElementById("dataLen");
const dataSign = document.getElementById("dataSign");

const filePathIpt = document.getElementById("filePath");
const filePathConvert = document.getElementById("filePathConvert");

const cmdRadio = document.getElementsByClassName("cmd_radio");

complete16String = num => {
  return num > 15 ? num.toString(16) : `0${num.toString(16)}`;
};

  // 求负数补码
  getCompleteNum = num => {
    let res;
    if (num < 0) {
      res = num + 256;
    } else {
      res = num;
    }
    return res;
  };

/**
 * @description: 滤波数据转换
 * @param {*}
 * @return {*}
 */
function transformData() {
  let str = '';
  let dataOut = [];
  const resultDataAry = [];
  let data = textarea.value;
  for (let i = 0; i < data.length; i += 4) {
    // let childValue = filter_HT(getComplement(data.slice(i, i + 4)));
    let childValue = getComplement(data.slice(i, i + 4)); // 归一化
    let filterValue = getComplementCode(Math.round(filter_HT(childValue) * 32768)); // 滤波返回的 flaot
    dataOut.push(filterValue % 256);
    dataOut.push(parseInt(filterValue / 256));
  }
  // console.log(dataOut);

  dataOut.forEach(item => {
  
    str += complete16String(getComplementCode(item));
  });

  console.log(str);


  // const resultData = getWebPcmTo8BitArrayBuffer(dataOut);

  // const wavFileCode = encodeWAV(resultData, 8000, 1, 16, true);

  // let blob = new Blob([wavFileCode], { type: "audio/wav" });

  // downloadWAV(blob, "testWav");
}

function getComplementCode(data) {
  if(data < 0) {
    data = parseInt((65535 + data));
  } else if(data === 0) {
    return 0;
  }
  return data;
}


function formatData() {
  let inputStr = textarea.value;
  textarea.value = trim(inputStr);
}

function trim(str){
	//从左侧开始替换空格
	str = str.replace(/^\s*/,"");
	//从左侧开始替换空格
  str = str.replace(/\s$/,"");
  str = str.replace(/[\r\n]/g,"");
	return str;
}

function handleWav() {
  let source = textarea.value;
  const hexAry = [],
    intAry = [];
  for (let i = 0; i < source.length - 1; i += 2) {
    hexAry.push(source.slice(i, i + 2));
  }

  if (hexAry.length > 0) {
    for (let i = 0; i < hexAry.length; i++) {
      intAry.push(hex2int(hexAry[i]));
    }
  }
  // console.log(hexAry);
  const resultData = getWebPcmTo8BitArrayBuffer(intAry);

  const wavFileCode = encodeWAV(resultData, 8000, 1, 16, true);

  let blob = new Blob([wavFileCode], { type: "audio/wav" });

  downloadWAV(blob, "testWav");
}

/**
 * 合并高低位并调换位置
 * @param sourceData
 * @return {Array}
 */
const checkDataSign = (sourceData) => {
  const convertData = [];
  for (let i = 0; i < sourceData.length - 2; i += 2) {
    convertData.push(getComplement(sourceData[i] + sourceData[i + 1]));
  }
  return convertData;
};

const int2Float = (num, fixed) => {
  return Number(num.toFixed(fixed));
};

/**
 * 将高低位数据归一化
 * @param sourceStr
 * @return {number}
 */
const getComplement = (sourceStr) => {
  let LInt = hex2int(sourceStr.slice(0, 2));
  let HInt = hex2int(sourceStr.slice(2, 4));

  let res = 0;
  if (HInt >= 128) {
    HInt = HInt - 128;
    res = HInt * 256 + LInt;
    res = res - 32767;
  } else {
    res = HInt * 256 + LInt;
  }
  res  = (res / 32768) * 10;
  if (res < -1) {
    res = -1;
  } else if (res > 1) {
    res = 1;
  }
  return res;
};

function hex2int(hex) {
  let len = hex.length,
    a = new Array(len),
    code;
  for (let i = 0; i < len; i++) {
    // charCodeAt 返回指定位置的字符的 unicode 编码
    code = hex.charCodeAt(i);
    if (code >= 48 && code < 58) {
      code -= 48;
    } else {
      code = (code & 0xdf) - 65 + 10;
    }
    a[i] = code;
  }
  return a.reduce(function (acc, c) {
    acc = 16 * acc + c;
    return acc;
  }, 0);
}

const getWebPcmTo8BitArrayBuffer = (sourceArr) => {
  const dataLength = sourceArr.length;
  const buffer = new ArrayBuffer(dataLength);
  const data = new DataView(buffer);
  for (let i = 0; i < sourceArr.length; i++) {
    // 范围 [-1, 1]
    // let s = Math.max(-1, Math.min(1, sourceArr[i]));
    // 对于 8 位的话，负数 * 128，正数 * 127，然后整体向上平移 128，即可得到 [0, 255 ] 范围的数据
    // let val = s < 0 ? s * 128 : s * 127;
    // val = parseInt(val + 128);
    data.setInt8(i, sourceArr[i]);
  }
  return data;
};

function writeString(data, offset, str) {
  for (let i = 0; i < str.length; i++) {
    data.setUint8(offset + i, str.charCodeAt(i));
  }
}

/**
 * pcm 数据转换为 wav 文件
 * @param bytes 音频数据
 * @param sampleRate 音频采样率
 * @param numChannels 声道数
 * @param outputSampleBits 音频采样位数
 * @param littleEdian 大小头，默认小头
 * @return {DataView}
 */
function encodeWAV(
  bytes,
  sampleRate,
  numChannels,
  sampleBits,
  littleEdian = true
) {
  let buffer = new ArrayBuffer(44 + bytes.byteLength),
    data = new DataView(buffer),
    channelCount = numChannels, // 声道
    offset = 0;

  // 资源交换文件标识符
  writeString(data, offset, "RIFF");
  offset += 4;
  // 下个地址开始到文件尾总字节数,即文件大小-8
  data.setUint32(offset, 36 + bytes.byteLength, littleEdian);
  offset += 4;
  // WAV文件标志
  writeString(data, offset, "WAVE");
  offset += 4;
  // 波形格式标志
  writeString(data, offset, "fmt ");
  offset += 4;
  // 过滤字节,一般为 0x10 = 16
  data.setUint32(offset, 16, littleEdian);
  offset += 4;
  // 格式类别 (PCM形式采样数据)
  data.setUint16(offset, 1, littleEdian);
  offset += 2;
  // 声道数
  data.setUint16(offset, channelCount, littleEdian);
  offset += 2;
  // 采样率,每秒样本数,表示每个通道的播放速度
  data.setUint32(offset, sampleRate, littleEdian);
  offset += 4;
  // 波形数据传输率 (每秒平均字节数) 声道数 × 采样频率 × 采样位数 / 8
  data.setUint32(
    offset,
    channelCount * sampleRate * (sampleBits / 8),
    littleEdian
  );
  offset += 4;
  // 快数据调整数 采样一次占用字节数 声道数 × 采样位数 / 8
  data.setUint16(offset, channelCount * (sampleBits / 8), littleEdian);
  offset += 2;
  // 采样位数
  data.setUint16(offset, sampleBits, littleEdian);
  offset += 2;
  // 数据标识符
  writeString(data, offset, "data");
  offset += 4;
  // 采样数据总数,即数据总大小-44
  data.setUint32(offset, bytes.byteLength, littleEdian);
  offset += 4;

  // 给wav头增加pcm体
  for (let i = 0; i < bytes.byteLength; i++, offset++) {
    data.setUint8(offset, bytes.getUint8(i));
  }
  return data;
}

function _download(blob, name, type) {
  let oA = document.createElement("a");
  oA.href = window.URL.createObjectURL(blob);
  oA.download = `${name}.${type}`;
  oA.click();
}

function downloadWAV(wavBLob, name) {
  _download(wavBLob, name, "wav");
}

const countCRC = (hexString) => {
  const hexAry = [];
  let sum = 0;
  for (let i = 0; i < hexString.length; i += 2) {
    sum += hex2int(hexString.slice(i, i + 2));
  }
  return (sum % 256).toString(16).toLowerCase();
};

const countLen = str => {
  const dataLen = str.length / 2;
  return dataLen > 15 ? dataLen.toString(16) : `0${dataLen.toString(16)}`;
};

const filePathTranslate = pathStr => {
  let hexAry = [];
  for(let i = 0; i < pathStr.length; i++) {
    hexAry.push(pathStr.charCodeAt(i));
  }
  return hexAry;
};

const handleClickToTranslate = () => {
  const val = filePathIpt.value;
  const asciiVal = filePathTranslate(val);
  let command = '';
  let hexStr = '';
  const hexVal = asciiVal.map(item => {
    return item.toString(16);
  });
  hexVal.forEach(item => {
    hexStr += item;
  })
  // console.log(hexStr);
  let cmdType = '';
  for (let i in cmdRadio) {
    if(cmdRadio[i].checked) {
      cmdType = cmdRadio[i].value;
    }
  }

  let comandLength = countLen(hexStr);

  command += `${cmdType}${comandLength}${hexStr}`;
  command += `${countCRC(command)}00`
  console.log(command);
  // console.log(countCRC(command));
  filePathConvert.innerText = command;
  // console.log(hexVal);
}

const ORDER_HT = 4;

const PARA_NUM_HT = [1,-3.69905687174103,5.14920434916213,-3.19928074902097,0.749180967484160];
const PARA_DEN_HT = [0.00908576605455529,0,-0.0181715321091106,0,0.00908576605455529];

let filter_x_HT = Array(ORDER_HT).fill(0);
let filter_y_HT = Array(ORDER_HT).fill(0);


function filter_HT(dataIn) {
  let dataOut = 0;

  for (let i = 0; i < ORDER_HT; i++) {
    dataOut += PARA_DEN_HT[i + 1] * filter_x_HT[i] - PARA_NUM_HT[i + 1] * filter_y_HT[i];
  }
  dataOut += PARA_DEN_HT[0] * dataIn;

  for (let j = ORDER_HT - 1; j > 0; j--) {
    filter_x_HT[j] = filter_x_HT[j - 1];
    filter_y_HT[j] = filter_y_HT[j - 1];
  }

  filter_x_HT[0] = dataIn;
  filter_y_HT[0] = dataOut;
  return dataOut;
}
// let obj = {};
// this.reduceData = this.tableData.reduce(function (list, cur) {
//   obj[cur.process] ? '' : obj[cur.process] = true && list.push(cur.process);
//   return list;
// }, []);

// obj[cur.process] ? '' : obj[cur.process] = true && list.push(cur.process);
